package com.hoshiicloud.saleorder.utils;

import com.hoshiicloud.common.rpc.Response;
import io.swagger.annotations.ApiOperation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import lombok.experimental.UtilityClass;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.reactive.result.method.RequestMappingInfo;
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;

/**
 * @author MarkerCCC
 * @date 2019-09-20 - 09:44
 */
@Configuration
public class ModuleUrlUtils {

    public static Response<LinkedMultiValueMap<String, String>> getUrlMapping(HttpServletRequest request) {
        WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getSession().getServletContext());
        RequestMappingHandlerMapping rmhp = wc.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> map = rmhp.getHandlerMethods();
        LinkedMultiValueMap<String, String> urlMessageLinkMultiValueMap = new LinkedMultiValueMap<>();
        HashSet<Class<?>> classes = new HashSet<>();
        map.forEach((requestMappingInfo, handlerMethod) -> {
            // 拿到一个类中的所有url
            Class<?> beanType = handlerMethod.getBeanType();
            classes.add(beanType);
        });

        for (Class<?> beanType : classes) {
            Method[] methods = beanType.getMethods();
            String simpleName = beanType.getSimpleName();
            RequestMapping requestAnnotation = beanType.getAnnotation(RequestMapping.class);
            String headUrl = "";
            if (requestAnnotation != null) {
                String[] valueArr = requestAnnotation.value();
                headUrl = valueArr[0];
            }

            for (Method method : methods) {
                ApiOperation apiOperationAnnotation = method.getAnnotation(ApiOperation.class);
                GetMapping getAnnotation = method.getAnnotation(GetMapping.class);
                PostMapping postAnnotation = method.getAnnotation(PostMapping.class);
                PutMapping putAnnotation = method.getAnnotation(PutMapping.class);
                DeleteMapping deleteAnnotation = method.getAnnotation(DeleteMapping.class);
                RequestMapping requestMethodAnnotation = method.getAnnotation(RequestMapping.class);
                if (getAnnotation != null) {
                    addLinkMultiValueMap(urlMessageLinkMultiValueMap, simpleName, headUrl, apiOperationAnnotation,
                            getAnnotation.value());
                }
                if (postAnnotation != null) {
                    addLinkMultiValueMap(urlMessageLinkMultiValueMap, simpleName, headUrl, apiOperationAnnotation,
                            postAnnotation.value());
                }
                if (putAnnotation != null) {
                    addLinkMultiValueMap(urlMessageLinkMultiValueMap, simpleName, headUrl, apiOperationAnnotation,
                            putAnnotation.value());
                }
                if (deleteAnnotation != null) {
                    addLinkMultiValueMap(urlMessageLinkMultiValueMap, simpleName, headUrl, apiOperationAnnotation,
                            deleteAnnotation.value());
                }
                if (requestAnnotation != null) {
                    addLinkMultiValueMap(urlMessageLinkMultiValueMap, simpleName, headUrl, apiOperationAnnotation,
                            requestMethodAnnotation.value());
                }
            }
        }
        return Response.data(urlMessageLinkMultiValueMap);
    }

    private static void addLinkMultiValueMap(LinkedMultiValueMap<String, String> urlMessageLinkMultiValueMap, String simpleName, String headUrl,
            ApiOperation annotation, String[] valueArr) {
        for (String value : valueArr) {
            if (annotation != null) {
                String annotationValue = annotation.value();
                urlMessageLinkMultiValueMap.add(simpleName, headUrl + value + ":" + annotationValue);
            } else {
                urlMessageLinkMultiValueMap.add(simpleName, headUrl + value);
            }
        }
    }
}
